package
{
	import Managers.MenuManager;
	
	import Menus.BaseMenu;
	
	import Players.Player;
	
	import Utils.Camera;
	import Utils.Key;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class Game
	{		
		//the Main class
		protected var topClass:Main;
		//canvases
		protected var backGroundBitmapData:BitmapData;
		protected var hudBitmapData:BitmapData;
		protected var canvasBitmapData:BitmapData;
		protected var canvasBitmap:Bitmap;
		
		//level data
		protected var levels:Array = new Array();
		protected var currentLevel:Level;
		protected var stageHeight:int;
		protected var stageWidth:int;
		
		
		//Cool 2D Camera
		protected var camera:Camera;
		//Main Player Class
		protected var currentPlayer:Player;
		//If you want multiple players
		protected var heros:Array = new Array();
		
		//game booleans
		protected var isPaused:Boolean = true;
		protected var isGameOver:Boolean = false;
		
		//keys
		protected var escapeKey:uint = Key.ESCAPE;
		protected var pauseKey:uint = Key.P;
		
		//manages the menus
		protected var menuManager:MenuManager;
		
		//public properties
		public function get Levels():Array{return levels;}
		public function get Hero():Player{return currentPlayer;}
		public function get IsPaused():Boolean{return isPaused;}	
		public function set IsGameOver(value:Boolean):void{isGameOver = value;}
		public function get CurrentLevel():Level{return currentLevel;}
		public function get BackGroundBitmapData():BitmapData{return backGroundBitmapData;}
		public function get CanvasBitmapData():BitmapData{return canvasBitmapData;}
		public function get TopClass():Main{return topClass;}
		public function get Menus():MenuManager{return menuManager;}
		
		public function Game(topClass:Main, stageWidth:int, stageHeight:int)
		{
			this.topClass = topClass;
			this.stageWidth = stageWidth;
			this.stageHeight = stageHeight;
		}
		
		public function Initialize():void
		{
			backGroundBitmapData = new BitmapData(stageWidth, stageHeight, false, 0x00B4FF);
			canvasBitmapData = new BitmapData(stageWidth, stageHeight, false, 0xffffff);
			hudBitmapData = new BitmapData(stageWidth, stageHeight, true, 0xffffff);
			canvasBitmap = new Bitmap(canvasBitmapData);
			menuManager = new MenuManager(this);
		}
		
		public function Load():void
		{
			
		}
		
		protected function addHero(hero:Player):void
		{
			heros.push(hero);
		}
		
		protected function addMenu(menu:BaseMenu):void
		{
			menuManager.addMenu(menu);
		}
		
		protected function addLevel(level:Level):void
		{
			levels.push(level);
		}
		
		public function KeyHandling(e:KeyboardEvent):void
		{
			if(!isPaused)
			{
				switch(e.keyCode)
				{
					case escapeKey:
						pauseGame();
						menuManager.FindMenu("Main");
						menuManager.Show();
						break;
					case pauseKey:
						pauseGame();
						menuManager.FindMenu("Pause");
						menuManager.Show();
						break;
				}
			}
			else
			{
				menuManager.HandleInput(e.keyCode);
			}
		}
		
		private function pauseGame():void
		{
			isPaused = true;
			canvasBitmap.visible = false;	
			currentLevel.PauseMusic();
		}
		
		private function unpauseGame():void
		{
			isPaused = false;
			canvasBitmap.visible = true;
			topClass.stage.focus = topClass.stage;
			menuManager.Hide();
		}
		
		public function Update(deltaTime:int):void
		{	
			if(isPaused)
			{
				//Updating camera, player, and level
				camera.Update(deltaTime);
				currentLevel.Update(deltaTime);
				currentPlayer.Update(deltaTime);
			}
			else
			{
				menuManager.Update(deltaTime);
			}
		}
		
		public function Draw():void
		{
			if(isPaused)
			{
				//background Drawing
				canvasBitmapData.copyPixels(backGroundBitmapData,backGroundBitmapData.rect, new Point(0,0)); //Blit Background of Current Level
				//Drawing Players and levels	
				canvasBitmapData = currentLevel.Draw(camera, canvasBitmapData);	
				canvasBitmapData = currentPlayer.Draw(camera, canvasBitmapData);
			}
			else
			{
				menuManager.Draw(canvasBitmapData);
			}
		}
		
		public function LostGame():void
		{
			isPaused = true;
			currentLevel.StopBackgroundMusic();
			if(topClass.contains(canvasBitmap))
			{
				topClass.removeChild(canvasBitmap);
			}
			menuManager.FindMenu("GameOver");
			menuManager.Show();
		}
		
		public function ResetLevel():void
		{
			if(!topClass.contains(canvasBitmap))
			{
				topClass.addChild(canvasBitmap);
			}
			currentPlayer.Reset();
			switchLevels(currentPlayer.CurrentLevel);
		}
		
		public function WonLevel():void
		{
			pauseGame();
			currentLevel.StopBackgroundMusic();
			//add levels if needed
			menuManager.FindMenu("Win");
			menuManager.Show();
		}
		
		public function switchLevels(level:Level):void
		{
			currentLevel = level;
			//currentLevel.RespawnEnemies();
			for(var index:int = 0; index < heros.length; index ++)
			{
				heros[index].Level = currentLevel;
			}
			//currentLevel.setHeroPosition();
			unpauseGame();
			currentLevel.PlayBackgroundMusic();
		}
		
		public function ResetGame():void
		{
			currentPlayer = null;
			backGroundBitmapData= null;
			canvasBitmapData = null;
			hudBitmapData = null;
			canvasBitmap = null;
			camera = null;
			heros.length = 0;
			currentLevel = null;
			levels.length = 0;
		}
	}
}